# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1080 -> 1.1081 # kernel/posix-timers.c 1.15 -> 1.16 # include/linux/time.h 1.13 -> 1.14 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/05/14 jes@wildopensource.com 1.1079.1.1 # [PATCH] ia64: gettimeoffset hooks # # Make it possible to plug in alternate time-offset sources, such as external # (e.g., chipset) timers or High-Performance Event Timer (HPET) etc. This # is needed on platforms where the cycle-counters on different CPUs may # drift apart from each other. # This patch contains the ia64-specific portion only. # -------------------------------------------- # 03/05/14 jes@wildopensource.com 1.1079.1.2 # [PATCH] cpu_idle() cleanup # # -------------------------------------------- # 03/05/14 davidm@tiger.hpl.hp.com 1.1079.1.3 # ia64: Patch by Arun Sharma: Undo bad sys32_select() fix: The biggest value of n below # is INT_MAX and the value of size for n = INT_MAX is 268435456. So I don't think # there'll be an overflow. # -------------------------------------------- # 03/05/14 schwab@suse.de 1.1079.1.4 # [PATCH] ia64: fix ia32 sched_{s,g}etaffinity() # # -------------------------------------------- # 03/05/14 davidm@tiger.hpl.hp.com 1.1079.1.5 # ia64: Fix SMP fph-handling. Patch by Asit Mallick with some additional # changes by yours truly. # -------------------------------------------- # 03/05/14 davidm@tiger.hpl.hp.com 1.1079.1.6 # ia64: Fix various minor merge errors and build errors. Fix page-fault handler # so it handles not-present translations for region 5 (patch by John Marvin). # -------------------------------------------- # 03/05/14 davidm@tiger.hpl.hp.com 1.1081 # Undo timer breakage. Makes profil() work again. # -------------------------------------------- # diff -Nru a/include/linux/time.h b/include/linux/time.h --- a/include/linux/time.h Thu May 15 13:42:05 2003 +++ b/include/linux/time.h Thu May 15 13:42:05 2003 @@ -26,16 +26,6 @@ #include #include -#include -#include -#ifndef div_long_long_rem - -#define div_long_long_rem(dividend,divisor,remainder) ({ \ - u64 result = dividend; \ - *remainder = do_div(result,divisor); \ - result; }) - -#endif /* * Have the 32 bit jiffies value wrap 5 minutes after boot @@ -69,52 +59,25 @@ #ifndef NSEC_PER_USEC #define NSEC_PER_USEC (1000L) #endif -/* - * We want to do realistic conversions of time so we need to use the same - * values the update wall clock code uses as the jiffie size. This value - * is: TICK_NSEC(TICK_USEC) (both of which are defined in timex.h). This - * is a constant and is in nanoseconds. We will used scaled math and - * with a scales defined here as SEC_JIFFIE_SC, USEC_JIFFIE_SC and - * NSEC_JIFFIE_SC. Note that these defines contain nothing but - * constants and so are computed at compile time. SHIFT_HZ (computed in - * timex.h) adjusts the scaling for different HZ values. - */ -#define SEC_JIFFIE_SC (30 - SHIFT_HZ) -#define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 30) -#define USEC_JIFFIE_SC (SEC_JIFFIE_SC + 20) -#define SEC_CONVERSION ((unsigned long)(((u64)NSEC_PER_SEC << SEC_JIFFIE_SC) /\ - (u64)TICK_NSEC(TICK_USEC))) -#define NSEC_CONVERSION ((unsigned long)(((u64)1 << NSEC_JIFFIE_SC) / \ - (u64)TICK_NSEC(TICK_USEC))) -#define USEC_CONVERSION \ - ((unsigned long)(((u64)NSEC_PER_USEC << USEC_JIFFIE_SC)/ \ - (u64)TICK_NSEC(TICK_USEC))) -#define MAX_SEC_IN_JIFFIES \ - (u32)((u64)((u64)MAX_JIFFY_OFFSET * TICK_NSEC(TICK_USEC)) / NSEC_PER_SEC) static __inline__ unsigned long timespec_to_jiffies(struct timespec *value) { unsigned long sec = value->tv_sec; - long nsec = value->tv_nsec + TICK_NSEC(TICK_USEC) - 1; + long nsec = value->tv_nsec; - if (sec >= MAX_SEC_IN_JIFFIES) + if (sec >= (MAX_JIFFY_OFFSET / HZ)) return MAX_JIFFY_OFFSET; - return (((u64)sec * SEC_CONVERSION) + - (((u64)nsec * NSEC_CONVERSION) >> - (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; - + nsec += 1000000000L / HZ - 1; + nsec /= 1000000000L / HZ; + return HZ * sec + nsec; } static __inline__ void jiffies_to_timespec(unsigned long jiffies, struct timespec *value) { - /* - * Convert jiffies to nanoseconds and seperate with - * one divide. - */ - u64 nsec = (u64)jiffies * TICK_NSEC(TICK_USEC); - value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec); + value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ); + value->tv_sec = jiffies / HZ; } /* Same for "timeval" */ @@ -122,25 +85,20 @@ timeval_to_jiffies(struct timeval *value) { unsigned long sec = value->tv_sec; - long usec = value->tv_usec + USEC_PER_SEC / HZ - 1; + long usec = value->tv_usec; - if (sec >= MAX_SEC_IN_JIFFIES) + if (sec >= (MAX_JIFFY_OFFSET / HZ)) return MAX_JIFFY_OFFSET; - return (((u64)sec * SEC_CONVERSION) + - (((u64)usec * USEC_CONVERSION) >> - (USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; + usec += 1000000L / HZ - 1; + usec /= 1000000L / HZ; + return HZ * sec + usec; } static __inline__ void jiffies_to_timeval(unsigned long jiffies, struct timeval *value) { - /* - * Convert jiffies to nanoseconds and seperate with - * one divide. - */ - u64 nsec = (u64)jiffies * TICK_NSEC(TICK_USEC); - value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec); - value->tv_usec /= NSEC_PER_USEC; + value->tv_usec = (jiffies % HZ) * (1000000L / HZ); + value->tv_sec = jiffies / HZ; } static __inline__ int timespec_equal(struct timespec *a, struct timespec *b) diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c --- a/kernel/posix-timers.c Thu May 15 13:42:05 2003 +++ b/kernel/posix-timers.c Thu May 15 13:42:05 2003 @@ -33,12 +33,7 @@ result; }) #endif -#define CLOCK_REALTIME_RES TICK_NSEC(TICK_USEC) // In nano seconds. -static inline u64 mpy_l_X_l_ll(unsigned long mpy1,unsigned long mpy2) -{ - return (u64)mpy1 * mpy2; -} /* * Management arrays for POSIX timers. Timers are kept in slab memory * Timer ids are allocated by an external routine that keeps track of the @@ -180,8 +175,8 @@ */ static __init int init_posix_timers(void) { - struct k_clock clock_realtime = {.res = CLOCK_REALTIME_RES }; - struct k_clock clock_monotonic = {.res = CLOCK_REALTIME_RES, + struct k_clock clock_realtime = {.res = NSEC_PER_SEC / HZ }; + struct k_clock clock_monotonic = {.res = NSEC_PER_SEC / HZ, .clock_get = do_posix_clock_monotonic_gettime, .clock_set = do_posix_clock_monotonic_settime }; @@ -209,14 +204,24 @@ } /* - * The scaling constants are defined in - * The difference between there and here is that we do the - * res rounding and compute a 64-bit result (well so does that - * but it then throws away the high bits). - */ - *jiff = (mpy_l_X_l_ll(sec, SEC_CONVERSION) + - (mpy_l_X_l_ll(nsec, NSEC_CONVERSION) >> - (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; + * A note on jiffy overflow: It is possible for the system to + * have been up long enough for the jiffies quanity to overflow. + * In order for correct timer evaluations we require that the + * specified time be somewhere between now and now + (max + * unsigned int/2). Times beyond this will be truncated back to + * this value. This is done in the absolute adjustment code, + * below. Here it is enough to just discard the high order + * bits. + */ + *jiff = (s64)sec * HZ; + /* + * Do the res thing. (Don't forget the add in the declaration of nsec) + */ + nsec -= nsec % res; + /* + * Split to jiffie and sub jiffie + */ + *jiff += nsec / (NSEC_PER_SEC / HZ); } static void schedule_next_timer(struct k_itimer *timr) @@ -1227,6 +1232,7 @@ finish_wait(&nanosleep_abs_wqueue, &abs_wqueue); if (left > (s64)0) { + unsigned long rmd; /* * Always restart abs calls from scratch to pick up any @@ -1235,10 +1241,9 @@ if (abs) return -ERESTARTNOHAND; - left *= TICK_NSEC(TICK_USEC); - tsave->tv_sec = div_long_long_rem(left, - NSEC_PER_SEC, - &tsave->tv_nsec); + tsave->tv_sec = div_long_long_rem(left, HZ, &rmd); + tsave->tv_nsec = rmd * (NSEC_PER_SEC / HZ); + restart_block->fn = clock_nanosleep_restart; restart_block->arg0 = which_clock; restart_block->arg1 = (unsigned long)tsave;